<template>
  <div>
    <el-card shadow="never">
      <!-- 表格工具栏 -->
      <div class="flex-x-between mb-[10px]">
        <!-- 左侧工具栏 -->
        <div>
          <template v-for="item in toolbar" :key="item">
            <template v-if="typeof item === 'string'">
              <!-- 新增 -->
              <template v-if="item === 'add'">
                <el-button :loading="requestStore.isRequestPending"
                           v-hasPerm="[`${contentConfig.pageName}:${item}`]"
                           type="success"
                           icon="plus"
                           @click="handleToolbar(item)"
                >
                  新增
                </el-button>
              </template>
              <!-- 删除 -->
              <template v-else-if="item === 'delete'">
                <el-button :loading="requestStore.isRequestPending"
                           v-hasPerm="[`${contentConfig.pageName}:${item}`]"
                           type="danger"
                           icon="delete"
                           :disabled="removeIds.length === 0"
                           @click="handleToolbar(item)"
                >
                  删除
                </el-button>
              </template>
              <!-- 导出 -->
              <template v-else-if="item === 'export'">
                <el-button :loading="requestStore.isRequestPending"
                           v-hasPerm="[`${contentConfig.pageName}:batchExport`]"
                           type="primary"
                           icon="download"
                           @click="handleToolbar(item)"
                >
                  根据查询条件导出
                </el-button>
              </template>
              <!-- 导入 -->
              <template v-else-if="item === 'import'">
                <el-button :loading="requestStore.isRequestPending"
                           v-hasPerm="[`${contentConfig.pageName}:batchImport`]"
                           type="primary"
                           icon="upload"
                           @click="handleToolbar(item)"
                >
                  导入
                </el-button>
              </template>
            </template>
            <!-- 其他 -->
            <template v-else-if="typeof item === 'object'">
              <template v-if="item.name.startsWith('custom')">
                <slot
                    :name="item.name"
                    v-bind="item"
                ></slot>
              </template>
              <template v-else>
                <el-button :loading="requestStore.isRequestPending"
                           v-hasPerm="[`${contentConfig.pageName}:${item.auth}`]"
                           :icon="item.icon"
                           :type="item.type ? item.type : 'default'"
                           @click="handleToolbar(item.name,selectedItem)"
                >
                  {{ item.text }}
                </el-button>
              </template>
            </template>
          </template>
        </div>
        <!-- 右侧工具栏 -->
        <div>
          <template v-for="item in defaultToolbar" :key="item">
            <!--操作说明-->
            <template v-if="item === 'operationGuidance'">
              <el-tooltip
                  class="box-item"
                  content="操作指引"
              >
                <el-button :loading="requestStore.isRequestPending" icon="InfoFilled" circle
                           @click="handleToolbar(item)"/>
              </el-tooltip>
            </template>
            <!-- 刷新 -->
            <template v-else-if="item === 'refresh'">
              <el-tooltip
                  class="box-item"
                  content="刷新页面"
              >
                <el-button :loading="requestStore.isRequestPending" icon="refresh" circle @click="handleToolbar(item)"/>
              </el-tooltip>
            </template>
            <!-- 列设置 -->
            <template v-else-if="item === 'filter'">
              <el-popover placement="bottom" trigger="click">
                <template #reference>
                  <el-button icon="Operation" circle/>
                </template>
                <el-scrollbar max-height="350px">
                  <template v-for="col in cols" :key="col">
                    <el-checkbox
                        v-if="col.prop"
                        v-model="col.show"
                        :label="col.label"
                    />
                  </template>
                </el-scrollbar>
              </el-popover>
            </template>
            <!-- 搜索 -->
            <template v-else-if="item === 'search'">
              <el-tooltip
                  class="box-item"
                  content="搜索"
              >
                <el-button :loading="requestStore.isRequestPending" icon="search" circle @click="handleToolbar(item)"/>
              </el-tooltip>
            </template>
          </template>
        </div>
      </div>
      <!-- 列表 -->
      <el-table
          stripe highlight-current-row
          :row-key="getRowKey"
          v-loading="loading"
          v-bind="contentConfig.table"
          :data="pageData"
          @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" :width="selectionColumn.width" align="center" v-if="selectionColumn"/>

        <el-table-column v-if="expandCols.length > 0" type="expand">
          <template #default="scope">
            <el-form label-position="left" label-width="auto" label-suffix="："
                     style="background-color: #eeeeee4f;padding-left: 10px">
              <template v-for="col in expandCols" :key="col">
                <el-form-item :label="col.label">
                  <!-- 显示图片 -->
                  <template
                      v-if="(col.template !== 'tool' && col.template !== 'custom') && (scope.row[col.prop] == null || scope.row[col.prop].toString().trim().length <= 0)">
                    -
                  </template>
                  <template v-else-if="col.template === 'image'">
                    <template v-if="col.prop">
                      <template v-if="Array.isArray(scope.row[col.prop])">
                        <template
                            v-for="(item, index) in scope.row[col.prop]"
                            :key="item"
                        >
                          <el-image
                              v-bind="col"
                              :src="item"
                              :preview-src-list="scope.row[col.prop]"
                              :initial-index="index"
                              :preview-teleported="true"
                              :style="`width: ${col.imageWidth ?? 40}px; height: ${col.imageHeight ?? 40}px`"
                          />
                        </template>
                      </template>
                      <template v-else>
                        <el-image
                            v-bind="col"
                            :src="baseUri + downloadPersonalFileUrl + scope.row[col.prop]+'&'+TOKEN_KEY+'='+accessToken"
                            :preview-src-list="[baseUri + downloadPersonalFileUrl +scope.row[col.prop]+'&'+TOKEN_KEY+'='+accessToken]"
                            :preview-teleported="true"
                            :style="`width: ${col.imageWidth ?? 40}px; height: ${col.imageHeight ?? 40}px`"
                        />
                      </template>
                    </template>
                  </template>
                  <!-- 根据行的selectList属性返回对应列表值 -->
                  <template v-else-if="col.template === 'list'">
                    <template v-if="col.prop">
                      <template v-if="scope.row[col.prop].toString().indexOf(',') != -1">
                        <template v-for="item in col.selectList">
                          <template v-if="(','+scope.row[col.prop].toString()+',').indexOf(','+item.value+',') != -1">
                            <template v-if="item.tag">
                              <el-tag :type="item.tag" size="small">
                                {{ item.label }}
                              </el-tag>
                            </template>
                            <template v-else>
                              {{ item.label }}
                            </template>
                          </template>
                        </template>
                      </template>
                      <template v-else>
                        <template
                            v-if="col.selectList.map(item => item.value+'').indexOf((scope.row[col.prop]+'')) < 0">
                          <!--                    不在列表中?！-->
                          <span style="color: red">{{ scope.row[col.prop] }}</span>
                        </template>
                        <template v-else v-for="item in col.selectList">
                          <template v-if="scope.row[col.prop].toString() == (item.value+'')">
                            <template v-if="item.tag">
                              <el-tag :type="item.tag" size="small">
                                {{ item.label }}
                              </el-tag>
                            </template>
                            <template v-else>
                              {{ item.label }}
                            </template>
                          </template>
                        </template>
                      </template>
                    </template>
                  </template>
                  <!-- 格式化显示链接 -->
                  <template v-else-if="col.template === 'url'">
                    <template v-if="col.prop">
                      <el-link
                          v-bind="col"
                          type="primary"
                          :href="scope.row[col.prop]"
                          target="_blank"
                      >
                        {{ scope.row[col.prop] }}
                      </el-link>
                    </template>
                  </template>
                  <!-- 生成开关组件 -->
                  <template v-else-if="col.template === 'switch'">
                    <template v-if="col.prop">
                      <!-- pageData.length>0: 解决el-switch组件会在表格初始化的时候触发一次change事件 -->
                      <el-switch
                          v-bind="col"
                          :style="'--el-switch-on-color: '+(col.activeColor?col.activeColor:'#409eff')+'; --el-switch-off-color: '+(col.inactiveColor?col.inactiveColor:'#dcdfe6')"
                          v-model="scope.row[col.prop]"
                          :active-value="col.activeValue ?? 1"
                          :inactive-value="col.inactiveValue ?? 0"
                          :inline-prompt="true"
                          :active-text="col.activeText ?? ''"
                          :inactive-text="col.inactiveText ?? ''"
                          :validate-event="false"
                          :disabled="!(col.rowEdit && hasAuth(`${contentConfig.pageName}:edit`))"
                          @change="
                    pageData.length > 0 &&
                      handleModify(col.prop, scope.row[col.prop], scope.row)
                  "
                      />
                    </template>
                  </template>
                  <!-- 生成输入框组件 -->
                  <template v-else-if="col.template === 'input'">
                    <template v-if="col.prop">
                      <el-input
                          v-bind="col"
                          v-model="scope.row[col.prop]"
                          :type="col.inputType ?? 'text'"
                          :disabled="!(col.rowEdit && hasAuth(`${contentConfig.pageName}:edit`))"
                          @blur="handleModify(col.prop, scope.row[col.prop], scope.row)"
                      />
                    </template>
                  </template>
                  <!-- 格式化为价格 -->
                  <template v-else-if="col.template === 'price'">
                    <template v-if="col.prop">
                      {{ `${col.priceFormat ?? "￥"}${scope.row[col.prop]}` }}
                    </template>
                  </template>
                  <!-- 格式化为百分比 -->
                  <template v-else-if="col.template === 'percent'">
                    <template v-if="col.prop"> {{ scope.row[col.prop] }}%</template>
                  </template>
                  <!-- 显示图标 -->
                  <template v-else-if="col.template === 'icon'">
                    <template v-if="col.prop">
                      <template v-if="scope.row[col.prop].startsWith('el-icon-')">
                        <el-icon v-bind="col">
                          <component
                              :is="scope.row[col.prop].replace('el-icon-', '')"
                          />
                        </el-icon>
                      </template>
                      <template v-else>
                        <svg-icon v-bind="col" :icon-class="scope.row[col.prop]"/>
                      </template>
                    </template>
                  </template>
                  <template v-else-if="col.template === 'desensitize'">
                    <template v-if="col.prop">
                      <text-desensitize v-model="scope.row[col.prop]" v-bind="col" style="text-align: left"/>
                    </template>
                  </template>
                  <!-- 格式化时间 -->
                  <template v-else-if="col.template === 'date'">
                    <template v-if="col.prop">
                      {{
                        useDateFormat(
                            scope.row[col.prop],
                            col.dateFormat ?? "YYYY-MM-DD HH:mm:ss"
                        ).value
                      }}
                    </template>
                  </template>
                  <!-- 列操作栏 -->
                  <template v-else-if="col.template === 'tool'">
                    <template
                        v-for="item in col.operat ?? ['edit', 'delete']"
                        :key="item"
                    >
                      <template v-if="typeof item === 'string'">
                        <!-- 编辑/删除 -->
                        <template v-if="item === 'edit' || item === 'delete'">
                          <el-button :loading="requestStore.isRequestPending"
                                     v-hasPerm="[`${contentConfig.pageName}:${item}`]"
                                     :type="item === 'edit' ? 'primary' : 'danger'"
                                     :icon="item"
                                     size="small"
                                     link
                                     @click="
                        handleOperat({
                          name: item,
                          row: scope.row,
                          column: scope.column,
                          $index: scope.$index,
                        })
                      "
                          >
                            {{ item === "edit" ? "编辑" : "删除" }}
                          </el-button>
                        </template>
                      </template>
                      <!-- 其他 -->
                      <template v-else-if="typeof item === 'object'">
                        <el-button :loading="requestStore.isRequestPending"
                                   v-hasPerm="[`${contentConfig.pageName}:${item.auth}`]"
                                   :disabled=" isDisabled(item.disabledCondition,scope.row) "
                                   :icon="item.icon"
                                   type="primary"
                                   size="small"
                                   link
                                   @click="
                      handleOperat({
                        name: item.name,
                        row: scope.row,
                        column: scope.column,
                        $index: scope.$index,
                      })
                    "
                        >
                          {{ item.text }}
                        </el-button>
                      </template>
                    </template>
                  </template>
                  <!-- 自定义 -->
                  <template v-else-if="col.template === 'custom'">
                    <slot
                        :name="col.slotName ?? col.prop"
                        :prop="col.prop"
                        v-bind="scope"
                    ></slot>
                  </template>

                  <template v-else>
                    <template v-if="col.prop">
                      <div style="white-space: pre-wrap">
                        {{ scope.row[col.prop] }}
                      </div>
                    </template>
                  </template>
                </el-form-item>

              </template>
            </el-form>
          </template>

        </el-table-column>

        <template v-for="col in cols" :key="col">

          <el-table-column v-if="col.show && col.template !== 'tool'" v-bind="col">
            <template #default="scope">
              <template
                  v-if="(col.template !== 'tool' && col.template !== 'custom') && (scope.row[col.prop] == null || scope.row[col.prop].toString().trim().length <= 0)">
                -
              </template>
              <!-- 显示图片 -->
              <template v-else-if="col.template === 'image'">
                <template v-if="col.prop">
                  <template v-if="Array.isArray(scope.row[col.prop])">
                    <template
                        v-for="(item, index) in scope.row[col.prop]"
                        :key="item"
                    >
                      <el-image
                          :src="item"
                          :preview-src-list="scope.row[col.prop]"
                          :initial-index="index"
                          :preview-teleported="true"
                          :style="`width: ${col.imageWidth ?? 40}px; height: ${col.imageHeight ?? 40}px`"
                      />
                    </template>
                  </template>
                  <template v-else>
                    <el-image
                        :src="baseUri + downloadPersonalFileUrl + scope.row[col.prop]+'&'+TOKEN_KEY+'='+accessToken"
                        :preview-src-list="[baseUri + downloadPersonalFileUrl +scope.row[col.prop]+'&'+TOKEN_KEY+'='+accessToken]"
                        :preview-teleported="true"
                        :style="`width: ${col.imageWidth ?? 40}px; height: ${col.imageHeight ?? 40}px`"
                    />
                  </template>
                </template>
              </template>
              <!-- 根据行的selectList属性返回对应列表值 -->
              <template v-else-if="col.template === 'list'">
                <template v-if="col.prop">
                  <template v-if="scope.row[col.prop].toString().indexOf(',') != -1">
                    <template v-for="item in col.selectList">
                      <template v-if="(','+scope.row[col.prop].toString()+',').indexOf(','+item.value+',') != -1">
                        <template v-if="item.tag">
                          <el-tag :type="item.tag" size="small">
                            {{ item.label }}
                          </el-tag>
                        </template>
                        <template v-else>
                          {{ item.label }}
                        </template>
                      </template>
                    </template>
                  </template>
                  <template v-else>
                    <template v-if="col.selectList.map(item => item.value+'').indexOf((scope.row[col.prop]+'')) < 0">
                      <!--                    不在列表中?！-->
                      <span style="color: red">{{ scope.row[col.prop] }}</span>
                    </template>
                    <template v-else v-for="item in col.selectList">
                      <template v-if="scope.row[col.prop].toString() == (item.value+'')">
                        <template v-if="item.tag">
                          <el-tag :type="item.tag" size="small">
                            {{ item.label }}
                          </el-tag>
                        </template>
                        <template v-else>
                          {{ item.label }}
                        </template>
                      </template>
                    </template>
                  </template>
                </template>
              </template>
              <!-- 格式化显示链接 -->
              <template v-else-if="col.template === 'url'">
                <template v-if="col.prop">
                  <el-link
                      type="primary"
                      :href="scope.row[col.prop]"
                      target="_blank"
                  >
                    {{ scope.row[col.prop] }}
                  </el-link>
                </template>
              </template>
              <!-- 生成开关组件 -->
              <template v-else-if="col.template === 'switch'">
                <template v-if="col.prop">
                  <!-- pageData.length>0: 解决el-switch组件会在表格初始化的时候触发一次change事件 -->
                  <el-switch
                      :style="'--el-switch-on-color: '+(col.activeColor?col.activeColor:'#409eff')+'; --el-switch-off-color: '+(col.inactiveColor?col.inactiveColor:'#dcdfe6')"
                      :loading="requestStore.isRequestPending"
                      v-model="scope.row[col.prop]"
                      :active-value="col.activeValue ?? '1'"
                      :inactive-value="col.inactiveValue ?? '0'"
                      :inline-prompt="true"
                      :active-text="col.activeText ?? ''"
                      :inactive-text="col.inactiveText ?? ''"
                      :validate-event="false"
                      :disabled="!(col.rowEdit && hasAuth(`${contentConfig.pageName}:edit`))"
                      @change=" pageData.length > 0 &&
                      handleModify(col.prop, scope.row[col.prop], scope.row)
                  "
                  />
                </template>
              </template>
              <!-- 生成输入框组件 -->
              <template v-else-if="col.template === 'input'">
                <template v-if="col.prop">
                  <el-input
                      v-model="scope.row[col.prop]"
                      :type="col.inputType ?? 'text'"
                      :disabled="!(col.rowEdit && hasAuth(`${contentConfig.pageName}:edit`))"
                      @blur="handleModify(col.prop, scope.row[col.prop], scope.row)"
                  />
                </template>
              </template>
              <!-- 格式化为价格 -->
              <template v-else-if="col.template === 'price'">
                <template v-if="col.prop">
                  {{ `${col.priceFormat ?? "￥"}${scope.row[col.prop]}` }}
                </template>
              </template>
              <!-- 格式化为百分比 -->
              <template v-else-if="col.template === 'percent'">
                <template v-if="col.prop"> {{ scope.row[col.prop] }}%</template>
              </template>
              <!-- 显示图标 -->
              <template v-else-if="col.template === 'icon'">
                <template v-if="col.prop">
                  <template v-if="scope.row[col.prop].startsWith('el-icon-')">
                    <el-icon>
                      <component
                          :is="scope.row[col.prop].replace('el-icon-', '')"
                      />
                    </el-icon>
                  </template>
                  <template v-else>
                    <svg-icon :icon-class="scope.row[col.prop]"/>
                  </template>
                </template>
              </template>
              <template v-else-if="col.template === 'desensitize'">
                <template v-if="col.prop">
                  <text-desensitize v-model="scope.row[col.prop]" v-bind="col"/>
                </template>
              </template>
              <!-- 格式化时间 -->
              <template v-else-if="col.template === 'date'">
                <template v-if="col.prop">
                  {{
                    useDateFormat(
                        scope.row[col.prop],
                        col.dateFormat ?? "YYYY-MM-DD HH:mm:ss"
                    ).value
                  }}
                </template>
              </template>
              <!-- 自定义 -->
              <template v-else-if="col.template === 'custom'">
                <slot
                    :name="col.slotName ?? col.prop"
                    :prop="col.prop"
                    v-bind="scope"
                ></slot>
              </template>
            </template>
          </el-table-column>
          <el-table-column v-hasPerm="toolColumnsPerm"
                           v-if="col.show && col.template === 'tool'" v-bind="col">
            <template #default="scope">
              <template
                  v-for="item in col.operat ?? ['edit', 'delete']"
                  :key="item"
              >
                <template v-if="typeof item === 'string'">
                  <!-- 编辑/删除 -->
                  <template v-if="item === 'edit' || item === 'delete'">
                    <el-button :loading="requestStore.isRequestPending"
                               v-hasPerm="[`${contentConfig.pageName}:${item}`]"
                               :type="item === 'edit' ? 'primary' : 'danger'"
                               :icon="item"
                               size="small"
                               link
                               @click="
                        handleOperat({
                          name: item,
                          row: scope.row,
                          column: scope.column,
                          $index: scope.$index,
                        })
                      "
                    >
                      {{ item === "edit" ? "编辑" : "删除" }}
                    </el-button>
                  </template>
                </template>
                <!-- 其他 -->
                <template v-else-if="typeof item === 'object'">
                  <el-button :loading="requestStore.isRequestPending"
                             v-hasPerm="[`${contentConfig.pageName}:${item.auth}`]"
                             :disabled=" isDisabled(item.disabledCondition,scope.row) "
                             :icon="item.icon"
                             :type="item.type ? item.type : 'primary'"
                             size="small"
                             link
                             @click="
                      handleOperat({
                        name: item.name,
                        row: scope.row,
                        column: scope.column,
                        $index: scope.$index,
                      })
                    "
                  >
                    {{ item.text }}
                  </el-button>
                </template>
              </template>
            </template>
          </el-table-column>
        </template>
      </el-table>
      <!-- 分页 -->
      <pagination
          v-if="total > 0"
          v-model:total="total"
          v-model:page="queryParams.pageNum"
          v-model:limit="queryParams.pageSize"
          @pagination="handlePagination"
      />
    </el-card>
    <el-tour v-model="tourOpen">
      <el-tour-step v-for="guidance in guidanceData || {}" :key="guidance"
                    :title="guidance.title"
                    :description="guidance.description"
                    :content-style="{ 'white-space': 'pre-wrap' }"
      />
    </el-tour>

    <el-dialog title="请选择模板" v-model="selectTemplateDialogVisible" width="80%"
               :loading="requestStore.isRequestPending" destroy-on-close>
      <div class="table-container">
        <el-form :inline="true" :model="selectTemplateListQuery" class="demo-form-inline">
          <el-form-item label="备注信息">
            <el-input v-model="selectTemplateListQuery.remark" placeholder="请输入备注信息" clearable/>
          </el-form-item>
          <el-form-item>
            <el-button icon="search" :loading="requestStore.isRequestPending" type="primary"
                       @click="handleSelectTemplateListQuery">查询
            </el-button>
          </el-form-item>
          <el-form-item>
            <el-button icon="refresh" :loading="requestStore.isRequestPending" @click="handleResetTemplateListQuery">
              重置
            </el-button>
          </el-form-item>
        </el-form>
        <el-table :data="selectTemplateList"
                  style="width: 100%;"
                  :loading="requestStore.isRequestPending" border>
          <el-table-column label="表名" align="center" prop="tableName" show-overflow-tooltip>
            <template #default="scope">
              {{ getTableNameByTable(scope.row.tableName) }}
            </template>
          </el-table-column>
          <el-table-column label="备注信息" align="center" prop="remark" show-overflow-tooltip/>
          <el-table-column v-if="selectTemplateListQuery.type == '0'" label="类型" align="center" prop="importType"
                           width="150">
            <template #default="scope">
              <el-tag v-if="scope.row.importType == '0'">增量导入</el-tag>
              <el-tag v-else-if="scope.row.importType == '1'" type="danger">全量导入-先删后增</el-tag>
            </template>
          </el-table-column>
          <el-table-column label="创建时间" align="center" prop="createTime" width="170"/>
          <el-table-column label="更新时间" align="center" prop="updateTime" width="170"/>
          <el-table-column label="操作" align="center" width="200">
            <template #default="scope">
              <div>
                <el-upload
                    v-if="scope.row.type == '0' && !scope.row.importPopFieldMap"
                    class="upload-demo"
                    action=""
                    :accept="'.xls, .xlsx'"
                    :limit="1"
                    :before-upload="beforeFileUpload"
                    :http-request="function(file:any){return handleSelectTemplateUpload(file,scope.row.id);}">
                  <el-button :loading="requestStore.isRequestPending" size="small" icon="upload" type="primary">
                    点击导入
                  </el-button>
                </el-upload>
                <div v-if="scope.row.type == '0' && scope.row.importPopFieldMap" style="margin-bottom: 10px">
                  <el-button :loading="requestStore.isRequestPending" @click="showImportDialog(scope.row)" size="small"
                             icon="upload" type="primary">点击导入
                  </el-button>
                </div>
                <el-button :loading="requestStore.isRequestPending" size="small" icon="download" type="primary"
                           @click="handleSelectTemplate(scope.row.id)"
                           v-if="scope.row.type == '1'">使用此模板导出
                </el-button>
                <el-button :loading="requestStore.isRequestPending" size="small" icon="download" type="warning"
                           @click="handleDownloadTemplate(scope.row.id)"
                           v-if="scope.row.type == '0'">下载模板
                </el-button>
              </div>
            </template>
          </el-table-column>
        </el-table>
        <pagination
            v-if="selectTemplateListQuery.total > 0"
            v-model:total="selectTemplateListQuery.total"
            v-model:page="selectTemplateListQuery.current"
            v-model:limit="selectTemplateListQuery.pageSize"
            @pagination="handleSelectTemplateListQuery"
        />
      </div>
    </el-dialog>

    <el-dialog title="导入" v-model="importDialogVisible" width="60%"
               :loading="requestStore.isRequestPending" destroy-on-close>

      <el-form ref="importDialogRef" :model="importDialogFormData" label-suffix="：" label-width="auto">
        <el-form-item v-for="item in importDialogFormListRef" :label="item.label" :rules="item.rules" :prop="item.prop">
          <el-input v-if="item.type=='input'" v-model="importDialogFormData[item.prop]"
                    :placeholder="'请输入'+item.label" clearable/>
          <el-select v-else :multiple="item.multiple" v-model="importDialogFormData[item.prop]" filterable>
            <el-option v-for="option in item.options" :key="option.value" :value="option.value" :label="option.label"/>
          </el-select>
        </el-form-item>
        <el-form-item label="文件" required>
          <el-upload
              style="width: 100%"
              ref="importDialogUploadRef"
              class="upload-demo"
              action=""
              :accept="'.xls, .xlsx'"
              :limit="1"
              :auto-upload="false"
              :on-remove="onRemoveFile"
              :on-change="onChangeFile"
              :before-upload="beforeFileUpload"
              :http-request="function(file:any){return handleSelectTemplateUploadForDialog(file);}">
            <el-button :loading="requestStore.isRequestPending" size="small" icon="upload" type="primary">选择文件
            </el-button>
          </el-upload>
        </el-form-item>
      </el-form>
      <template #footer>
        <div>
          <el-button @click="importDialogVisible = false">取消</el-button>
          <el-button :loading="requestStore.isRequestPending" @click="handleImportDialogSubmit" type="primary">导入
          </el-button>
        </div>
      </template>

    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import {useRequestStore} from '@/store';
import {reactive, ref} from "vue";
import {useDateFormat} from "@vueuse/core";
import {hasAuth} from "@/plugins/permission";
import Pagination from "@/components/Pagination/index.vue";
import SvgIcon from "@/components/SvgIcon/index.vue";
import BatchImportExportConfigAPI from "@/api/batchImportExportConfig/index";
import type {FormInstance, TableProps, UploadFile, UploadFiles, UploadInstance} from "element-plus";
import {TOKEN_KEY} from "@/enums/CacheEnum";
import {useRouter} from 'vue-router'
import request from "@/utils/request";
import TextDesensitize from "../TextDesensitize/index.vue";

const props = defineProps<{
  contentConfig: IContentConfig;
}>();

/*********************导入导出相关 start*************************/
const importDialogVisible = ref(false);
const importDialogFormListRef = ref([]);
const importDialogFormData = ref({});
const importDialogConfigId = ref("0");
var importDialogRef = ref<FormInstance>();
var importDialogUploadRef = ref<UploadInstance>();
const importFileNum = ref(0);
const showImportDialog = (row: any) => {
  importDialogConfigId.value = row.id;
  importDialogFormData.value = {};
  let importDialogFormList = []
  let importPopFieldMap = row.importPopFieldMap || {}
  for (let key in importPopFieldMap) {
    let desc = importPopFieldMap[key].desc;
    let type = importPopFieldMap[key].type;
    let option = []
    let multiple = false
    let radioOption = importPopFieldMap[key].radioOption;
    let associationTable = importPopFieldMap[key].associationTable;
    if (radioOption) {
      for (let k in radioOption) {
        option.push({
          label: radioOption[k],
          value: k.toString(),
        });
      }
      type = type.toLowerCase();
      if (type == 'checkbox' || type == 'selectmutil') {
        multiple = true
      }
      type = "select";
    } else if (associationTable) {
      let colArr = cols.value || []
      for (let i = 0; i < colArr.length; i++) {
        const col = colArr[i];
        if (col.prop === key) {
          option = col.selectList || []
          type = "select";
          break;
        }
      }
    } else {
      type = "input";
    }

    let importDialogFormItem = {
      label: desc,
      prop: key,
      type: type,
      placeholder: "请输入" + desc,
      options: option,
      multiple: multiple,
      rules: [
        {
          required: importPopFieldMap[key].required,
          message: "请输入" + desc,
          trigger: "blur",
        },
      ],
    };
    importDialogFormList.push(importDialogFormItem);
    importDialogFormListRef.value = importDialogFormList
  }
  importDialogVisible.value = true;
  importDialogRef = ref<FormInstance>();
  importDialogUploadRef = ref<UploadInstance>();
}

function onChangeFile(uploadFile: UploadFile, uploadFiles: UploadFiles) {
  importFileNum.value = uploadFiles.length;
}

function onRemoveFile() {
  importFileNum.value = 0;
}

function handleImportDialogSubmit() {
  if (importFileNum.value == 0) {
    ElMessage.error("请选择文件!");
    return;
  } else {
    importDialogRef.value?.validate((valid: boolean) => {
      if (valid) {
        importDialogUploadRef.value!.submit()
      } else {
        ElMessage.error("请先填写表单!");
      }
    })
  }
}

function handleSelectTemplateUploadForDialog(file: any) {
  handleSelectTemplateUpload(file, importDialogConfigId.value, importDialogFormData.value);
}


function camelToSnake(camelStr: string): string {
  if (!camelStr) {
    return '';
  } else if (camelStr.indexOf(":") != -1) {
    let datasourceStr = camelStr.substring(0, camelStr.indexOf(":"));
    let tableName = camelStr.substring(camelStr.indexOf(":") + 1);
    tableName = tableName.replace(/([A-Z])/g, '_$1').toLowerCase();
    return datasourceStr + "#" + tableName;
  } else {
    return camelStr.replace(/([A-Z])/g, '_$1').toLowerCase();
  }
}

const selectTemplateDialogVisible = ref(false);
const selectTemplateList = ref([]);
const selectTemplateListQuery = ref({
  current: 1,
  pageSize: 10,
  tableName: camelToSnake(props.contentConfig.pageName),
  type: undefined,
  remark: undefined,
  total: 0,
  status: 1,
});

function getTableNameByTable(table: string) {
  return sessionStorage.getItem("ALL_TABLE_INFO") ?
      JSON.parse(sessionStorage.getItem("ALL_TABLE_INFO") as string).find((item: any) => item.value === table).label : table
}

function handleResetTemplateListQuery() {
  selectTemplateListQuery.value.remark = undefined
  selectTemplateDialogVisible.value = true
  selectTemplateListQuery.value.current = 1
  selectTemplateListQuery.value.pageSize = 10
  handleSelectTemplateListQuery()
}

function handleSelectTemplateListQuery() {
  if (!selectTemplateListQuery.value.tableName) {
    selectTemplateListQuery.value.tableName = camelToSnake(props.contentConfig.pageName)
  }
  BatchImportExportConfigAPI.service("query", selectTemplateListQuery.value).then((response: any) => {
    if (response) {
      selectTemplateList.value = response.data.records
      selectTemplateListQuery.value.total = response.data.total
    }
  })
}

function beforeFileUpload(file: any) {
  const isExcel = file.type === 'application/vnd.ms-excel' || file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
  const isLt5M = file.size / 1024 / 1024 < 5;
  if (!isExcel) {
    ElMessage.error('上传文件只能是 xls/xlsx 格式文件');
  }
  if (!isLt5M) {
    ElMessage.error('上传文件大小不能超过 5MB!');
  }
  return isExcel && isLt5M;
}

const router = useRouter()

function handleSelectTemplateUpload(file: any, configId: string, addParam: any = {}) {
  let params = new FormData()
  params.append("xlsFile", file.file);
  params.append("configId", configId);
  for (let ap in addParam) {
    params.append(ap, addParam[ap]);
  }
  let headers = {
    'Content-Type': 'multipart/form-data; name="xlsFile"'
  }
  let pageName = props.contentConfig.pageName.split(":").join("/");
  request({
    url: "/api/" + pageName + "/batchImport",
    method: "post",
    data: params,
    headers: headers
  }).then((response: any) => {
    if (response) {
      if (response.data && response.data.taskId) {
        ElNotification({
          title: '提示',
          dangerouslyUseHTMLString: true,
          message: h('p', null, [
            h('span', '已经开始处理了，请在个人中心-下载管理中查看进度。本次任务编号:'),
            h('strong', {style: 'color: red'}, response.data.taskId),
            h('div'),
            h('a', {
              style: 'color: #409EFF;text-decoration:underline;',
              onClick: () => {
                router.push({
                  path: '/user/download',
                  query: {taskId: response.data.taskId}
                })
              }
            }, '立即查看'),
          ]),
          type: 'success',
        })
      } else if (response.message) {
        ElMessage({
          message: response.message,
          type: response.status ? 'success' : 'error'
        })
      }
    }
    handleRefresh()
    selectTemplateDialogVisible.value = false
    importDialogVisible.value = false
  }).catch(err => {
    console.error('Failed to load module', err);
  });
}

function handleSelectTemplate(configId: string) {
  let params = {
    configId: configId,
    ...lastFormData
  }
  let pageName = props.contentConfig.pageName.split(":").join("/");

  request({
    url: "/api/" + pageName + "/batchExport",
    method: "post",
    data: params,
  }).then((response: any) => {
    if (response) {
      if (response.data && response.data.taskId) {
        ElNotification({
          title: '提示',
          dangerouslyUseHTMLString: true,
          message: h('p', null, [
            h('span', '已经开始处理了，请在个人中心-下载管理中查看进度。本次任务编号:'),
            h('strong', {style: 'color: red'}, response.data.taskId),
            h('div'),
            h('a', {
              style: 'color: #409EFF;text-decoration:underline;',
              onClick: () => {
                router.push({
                  path: '/user/download',
                  query: {taskId: response.data.taskId}
                })
              }
            }, '立即查看'),
          ]),
          type: 'success',
        })
      } else if (response.message) {
        ElMessage({
          message: response.message,
          type: response.status ? 'success' : 'error'
        })
      }
    }
    selectTemplateDialogVisible.value = false
  }).catch(err => {
    console.error('Failed to load module', err);
  });

}

function handleDownloadTemplate(configId: string) {
  BatchImportExportConfigAPI.download("getImportExcel", {configId: configId}).then((response: any) => {
    if (response && response.message) {
      ElMessage({
        message: response.message,
        type: response.status ? 'success' : 'error'
      })
    }
  })
}

/*********************导入导出相关 end*************************/

const baseUri = import.meta.env.VITE_APP_BASE_API;
const downloadPersonalFileUrl = "/api/sysFile/downloadPersonalFile?fileId=";
const accessToken = sessionStorage.getItem(TOKEN_KEY);

const requestStore = useRequestStore();

function getRowKey(row: any): string {
  if (typeof props.contentConfig.pk == "string") {
    return row[props.contentConfig.pk]
  } else if (typeof props.contentConfig.pk == "object") {
    return props.contentConfig.pk.reduce((pre: string, cur: string) => {
      return pre + row[cur] + "$$";
    }, "");
  } else {
    return "id";
  }
}

// 对象类型
export type IObject = Record<string, any>;

// 定义接收的属性
export interface IOperatData {
  name: string;
  row: any;
  column: any;
  $index: number;
}

export interface IContentConfig<T = any> {
  // 页面名称(参与组成权限标识,如sys:user:xxx)
  pageName: string;
  // table组件属性
  table?: Omit<TableProps<any>, "data">;
  // 列表的网络请求函数(需返回promise)
  indexAction: (queryParams: T) => Promise<any>;
  // 删除的网络请求函数(需返回promise)
  deleteAction?: (ids: string) => Promise<any>;
  // 导出的网络请求函数(需返回promise)
  exportAction?: (queryParams: T) => Promise<any>;
  // 修改属性的网络请求函数(需返回promise)
  modifyAction?: (data: {
    [key: string]: any;
    field: string;
    value: boolean | string | number;
  }) => Promise<any>;
  // 主键名(默认为id)
  pk?: string | string[];
  // 表格工具栏(默认支持add,delete,export,也可自定义)
  toolbar?: Array<
      | "add"
      | "delete"
      | "export"
      | "import"
      | {
    auth: string;
    icon?: string;
    name: string;
    text: string;
    type?: string;
  }
  >;
  // 表格工具栏右侧图标
  defaultToolbar?: ("refresh" | "filter" | "search" | "operationGuidance")[];

  guidanceData?: Array<{
    title: string;
    description: string;
    contentStyle?: string
  }>;
  // table组件列属性(额外的属性template,operat,slotName)
  cols: Array<{
    initFn?: () => void;
    rowEdit?: boolean;
    //是否在expand中显示
    expand?: boolean;
    type?: "default" | "selection" | "index" | "expand";
    label?: string;
    prop?: string;
    width?: string | number;
    align?: "left" | "center" | "right";
    show?: boolean;
    template?:
        | "image"
        | "list"
        | "url"
        | "switch"
        | "input"
        | "price"
        | "percent"
        | "icon"
        | "date"
        | "desensitize"
        | "tool"
        | "custom";
    imageWidth?: number;
    imageHeight?: number;
    selectList?: Record<string, any>; // {label: "否", value: "0",tag: "primary"}
    activeValue?: boolean | string | number;
    inactiveValue?: boolean | string | number;
    activeText?: string;
    inactiveText?: string;
    activeColor?: string;
    inactiveColor?: string;
    inputType?: string;
    priceFormat?: string;
    dateFormat?: string;
    operat?: Array<
        | "edit"
        | "delete"
        | {
      auth: string;
      disabledCondition?: { field: string, values: string[] };
      icon?: string;
      name: string;
      text: string;
      type?: string;
    }
    >;
    [key: string]: any;
  }>;
}


// 定义自定义事件
const emit = defineEmits<{
  addClick: [];
  exportClick: [];
  searchClick: [];
  operationGuidanceClick: [];
  toolbarClick: [name: string, selectedItem?: IObject[]];
  editClick: [row: IObject];
  operatClick: [data: IOperatData];
}>();

// 主键
const pk = props.contentConfig.pk ?? "id";
// 表格左侧工具栏
const toolbar = props.contentConfig.toolbar ?? ["add", "delete"];
// 表格右侧工具栏
const defaultToolbar = props.contentConfig.defaultToolbar ?? [
  "operationGuidance",
  "refresh",
  "filter",
  "search"
];
const expandCols = ref<any>([])
const selectionColumn = ref<any>(undefined)

const guidanceData = props.contentConfig.guidanceData ?? [{title: "提示", description: "暂无说明"}];
const toolColumnsPerm = ref([])
// 表格列
const cols = ref(
    props.contentConfig.cols.filter((col) => {
      col.initFn && col.initFn();
      if (col.type == 'selection') {
        selectionColumn.value = col
        return false
      }
      if (col.show === undefined) {
        col.show = true;
      }
      if (col.template == 'tool') {
        let arr = col.operat || []
        if (arr.length == 0) {
          toolColumnsPerm.value = [`${props.contentConfig.pageName}:edit`, `${props.contentConfig.pageName}:delete`]
        } else {
          arr.map(item => {
            toolColumnsPerm.value.push(`${props.contentConfig.pageName}:` + item.auth)
          })
        }
      }

      if (col.expand) {
        expandCols.value.push(col)
        return false;
      } else {
        return true;
      }
    })
);


// 加载状态
const loading = ref(false);

//漫游指引窗口
const tourOpen = ref(false)
// 删除ID集合 用于批量删除
const removeIds = ref<(number | string)[]>([]);

// 选中项
const selectedItem = ref<(IObject)[]>([]);
// 数据总数
const total = ref(0);
// 列表数据
const pageData = ref<IObject[]>([]);
// 每页条数
const pageSize = 10;
// 搜索参数
const queryParams = reactive<IObject>({
  pageNum: 1,
  pageSize: pageSize,
});
// 上一次搜索条件
let lastFormData = {};

// 获取分页数据
function fetchPageData(formData: IObject = {}, isRestart = false) {
  loading.value = true;
  lastFormData = formData;
  if (isRestart) {
    queryParams.pageNum = 1;
    queryParams.pageSize = pageSize;
  }
  props.contentConfig
      .indexAction({...queryParams, ...formData})
      .then((data) => {
        total.value = data.data.total;
        pageData.value = data.data.records;
      })
      .finally(() => {
        loading.value = false;
      });
}

fetchPageData(lastFormData);

// 行选中
function handleSelectionChange(selection: any[]) {
  if (typeof pk == "string") {
    removeIds.value = selection.map((item) => item[pk]);
  } else if (typeof pk == "object") {
    removeIds.value = selection.map((item) => {
      const keys = pk.map((key, index) => item[key]);
      return keys.join('$$');
    });
  }
  selectedItem.value = selection;
}

function getSelectIds() {
  return removeIds.value
}

function getSelectedItem() {
  return selectedItem.value
}

// 刷新
function handleRefresh() {
  fetchPageData(lastFormData);
}

function operationGuidanceClick() {
  tourOpen.value = true;
}

// 删除
function handleDelete(id?: number | string) {
  let ids: string;
  if (id !== undefined) {
    // 如果传入了 id，则使用该 id
    ids = String(id);
  } else {
    // 否则使用 removeIds.value 数组
    ids = removeIds.value.join(",");
  }
  if (!ids) {
    ElMessage.warning("请勾选删除项");
    return;
  }

  ElMessageBox.confirm("确认删除?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(function () {
    if (props.contentConfig.deleteAction) {
      props.contentConfig.deleteAction(ids).then((response) => {
        ElMessage({
          message: response.message,
          type: response.status ? 'success' : 'error'
        })
        handleRefresh()
      });
    } else {
      ElMessage.error("未配置deleteAction");
    }
  }).catch(function () {
    ElMessage.info("取消操作");
  });
}

// 分页
function handlePagination() {
  fetchPageData(lastFormData);
}

// 操作栏  自定义的操作栏，selectedItem实际上就是列表选中项
function handleToolbar(name: string, selectedItem?: IObject[]) {
  switch (name) {
    case "refresh":
      handleRefresh();
      break;
    case "search":
      emit("searchClick");
      break;
    case "add":
      emit("addClick");
      break;
    case "delete":
      handleDelete();
      break;
    case "export":
      selectTemplateListQuery.value.type = 1
      handleResetTemplateListQuery();
      break;
    case "import":
      selectTemplateListQuery.value.type = 0
      handleResetTemplateListQuery();
      break;
    case "operationGuidance":
      operationGuidanceClick()
      break;
    default:
      emit("toolbarClick", name, selectedItem);
      break;
  }
}

// 操作列
function handleOperat(data: IOperatData) {
  switch (data.name) {
    case "edit":
      emit("editClick", data.row);
      break;
    case "delete":
      let ids = ''
      if (typeof pk == "string") {
        ids = data.row[pk];
      } else if (typeof pk == "object") {
        for (let i = 0; i < pk.length; i++) {
          if (i == 0) {
            ids = data.row[pk[i]]
          } else {
            ids += '$$' + data.row[pk[i]]
          }
        }
      }
      handleDelete(ids);
      break;
    default:
      emit("operatClick", data);
      break;
  }
}

// 导出Excel 已弃用
function exportPageData(queryParams: IObject = {}) {
  if (props.contentConfig.exportAction) {
    props.contentConfig.exportAction(queryParams).then((response) => {
      const fileData = response.data;
      const fileName = decodeURI(
          response.headers["content-disposition"].split(";")[1].split("=")[1]
      );
      const fileType =
          "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8";

      const blob = new Blob([fileData], {type: fileType});
      const downloadUrl = window.URL.createObjectURL(blob);
      const downloadLink = document.createElement("a");
      downloadLink.href = downloadUrl;
      downloadLink.download = fileName;
      document.body.appendChild(downloadLink);
      downloadLink.click();
      document.body.removeChild(downloadLink);
      window.URL.revokeObjectURL(downloadUrl);
    });
  } else {
    ElMessage.error("未配置exportAction");
  }
}

// 属性修改
function handleModify(
    field: string,
    value: boolean | string | number,
    row: Record<string, any>
) {
  if (props.contentConfig.modifyAction) {
    let params: any = {}
    params[field] = value;
    if (typeof pk == "string") {
      params[pk] = row[pk];
    } else if (typeof pk == "object") {
      for (let i = 0; i < pk.length; i++) {
        params[pk[i]] = row[pk[i]]
      }
    }
    props.contentConfig.modifyAction(params).then((response) => {
      ElMessage({
        message: response.message,
        type: response.status ? 'success' : 'error'
      })
      handleRefresh()
    });
  } else {
    ElMessage.error("未配置modifyAction");
  }
}

function isDisabled(
    disabledCondition?: {
      field: string,
      values: string[],
    },
    row?: Record<string, any>
) {

  if (disabledCondition && row) {
    return disabledCondition.values?.includes(row[disabledCondition.field]);
  }
}

// 暴露的属性和方法
defineExpose({fetchPageData, exportPageData, getSelectIds, getSelectedItem});
</script>


<style lang="scss" scoped>
</style>
